#!/bin/bash

# 模块名称
# moduleName=server-module/jenkins-demo-sever
moduleName=$1

# 镜像版本
image_version=$2

# docker分配内存大小(默认1024M)
docker_size=${3:-1024}

# JVM参数(默认最大堆内存256M 初始128M)
java_opts=${4:- -Xmx256M -Xms128M}

# 获取镜像名称
images_name="${moduleName}-master:${image_version}"

# 从模块名称中提取系统名称
OLD_IFS="$IFS"  # 保存原始的字段分隔符
IFS='/'  # 将字段分隔符设置为斜杠 '/'
array=($moduleName)  # 将模块名称按斜杠分割成数组
IFS="$OLD_IFS"  # 恢复原始的字段分隔符
system_name=""  # 初始化系统名称变量

# 遍历数组，获取最后一个部分作为系统名称
for var in "${array[@]}"; do
  system_name="${var}"
done

# 定义一个函数，用于检查指定端口是否被监听
function Listening() {
  # 获取 TCP 协议下处于监听状态的端口数量
  TCPListeningnum=$(netstat -an | grep ":$1 " | awk '/^tcp.*/ && $NF == "LISTEN" {print $0}' | wc -l)
  # 获取 UDP 协议下处于监听状态的端口数量
  UDPListeningnum=$(netstat -an | grep ":$1 " | awk '/^udp.*/ && $NF == "0.0.0.0:*" {print $0}' | wc -l)
  # 计算总监听端口数量
  ((Listeningnum = TCPListeningnum + UDPListeningnum))
  # 如果没有监听则返回 0，否则返回 1
  if [ $Listeningnum == 0 ]; then
    echo "0"
  else
    echo "1"
  fi
}

# 随机port函数，用于生成指定范围内的随机数
function random_range() {
  shuf -i $1-$2 -n1
}

# arr函数，用于检查某个值是否在数组中
function in_arr() {
  arr=$1
  echo "${arr[@]}" | grep -wq "$var" && echo 1 || echo 0
}

# 随机port函数，用于获取随机可用端口
function get_random_port() {
  temp1=0
  while [ 1 ]; do
    temp1=$(random_range $1 $2)
    if [ $(Listening $temp1) == 0 ] && [ $(in_arr $3) == 0 ]; then
      echo $temp1
      break
    fi
  done
}

# 端口数组
port_arr=()

# 获取 HTTP 端口
http_port=$(get_random_port 1000 9999 "${port_arr[@]}")
port_arr[0]=$http_port  # 将 HTTP 端口添加到数组中

# 获取 XXL-JOB 端口
xxl_job_port=$(get_random_port 1000 9999 "${port_arr[@]}")

# 获取服务器 IP 地址
ip_addr=$(ip addr show | grep inet | grep eth0 | awk '{print $2}' | awk -F '/' '{print $1}')

# 构建 Docker 运行命令
# 在容器名称前面的参数, 会被docker视为传递为内部的命令
# 在容器名称后面的参数, 会被解析为其他参数(JVM等..)

docker_run_cmd="docker run --memory=${docker_size}M -d \
-p 0.0.0.0:${http_port}:8080 \
-p 0.0.0.0:${xxl_job_port}:${xxl_job_port} \
--restart=on-failure:5 \
--name=${moduleName}-${http_port} \
${images_name} \
${java_opts} \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/logs/my-heap-dump.hprof \
-Xloggc:/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps \
--spring.cloud.nacos.discovery.ip=${ip_addr} \
--spring.cloud.nacos.discovery.port=${http_port} \
--job.ip=${ip_addr} \
--job.port=${xxl_job_port}"

# 输出镜像名称、IP 地址、端口信息和 Docker 运行命令
echo "------------------------------------------------------------"
echo ""
echo "docker_images_name: ${images_name}"
echo "ip_addr: ${ip_addr}, http_port: ${http_port}, xxl_job_port: ${xxl_job_port}"
echo "docker run command: "
echo "$docker_run_cmd"
echo ""
echo "------------------------------------------------------------"

# 执行 Docker 运行命令
eval $docker_run_cmd

##################
# 注意:
# 如果在windows下编辑脚本, 然后放在Linux下执行失败
# 很大原因是win和linux换行符不一致导致的报错
# 如果报错, 建议直接复制, 然后在Linux Vim编辑器粘贴使用
##################


